package gomysql

import (
	"go-micro-framework/go_service/core/gomysql/internal"
	"strings"
)

type Function struct {
	alias string
}

func (f *Function) As(asName any) string {
	return f.alias + " " + internal.As + " " + getColumnName(asName)
}

func (f *Function) Eq(value int64) (string, int64) {
	return buildalias(f.alias, internal.Eq, value)
}

func (f *Function) Ne(value int64) (string, int64) {
	return buildalias(f.alias, internal.Ne, value)
}

func (f *Function) Gt(value int64) (string, int64) {
	return buildalias(f.alias, internal.Gt, value)
}

func (f *Function) Ge(value int64) (string, int64) {
	return buildalias(f.alias, internal.Ge, value)
}

func (f *Function) Lt(value int64) (string, int64) {
	return buildalias(f.alias, internal.Lt, value)
}

func (f *Function) Le(value int64) (string, int64) {
	return buildalias(f.alias, internal.Le, value)
}

func (f *Function) In(values ...any) (string, []any) {
	// 构建占位符
	placeholder := buildPlaceholder(values)
	return f.alias + " " + internal.In + placeholder.String(), values
}

func (f *Function) NotIn(values ...any) (string, []any) {
	// 构建占位符
	placeholder := buildPlaceholder(values)
	return f.alias + " " + internal.Not + " " + internal.In + placeholder.String(), values
}

func (f *Function) Between(start int64, end int64) (string, int64, int64) {
	return f.alias + " " + internal.Between + " ? " + internal.And + " ?", start, end
}

func (f *Function) NotBetween(start int64, end int64) (string, int64, int64) {
	return f.alias + " " + internal.Not + " " + internal.Between + " ? " + internal.And + " ?", start, end
}

func Sum(columnName any) *Function {
	return &Function{alias: addBracket(internal.SUM, getColumnName(columnName))}
}

func Avg(columnName any) *Function {
	return &Function{alias: addBracket(internal.AVG, getColumnName(columnName))}
}

func Max(columnName any) *Function {
	return &Function{alias: addBracket(internal.MAX, getColumnName(columnName))}
}

func Min(columnName any) *Function {
	return &Function{alias: addBracket(internal.MIN, getColumnName(columnName))}
}

func Count(columnName any) *Function {
	return &Function{alias: addBracket(internal.COUNT, getColumnName(columnName))}
}

func As(columnName any, asName any) string {
	return getColumnName(columnName) + " " + internal.As + " " + getColumnName(asName)
}

func addBracket(function string, columnNameStr string) string {
	return function + internal.LeftBracket + columnNameStr + internal.RightBracket
}

func buildalias(alias string, typeStr string, value int64) (string, int64) {
	return alias + " " + typeStr + " ?", value
}

func buildPlaceholder(values []any) strings.Builder {
	var placeholder strings.Builder
	placeholder.WriteString(internal.LeftBracket)
	for i := 0; i < len(values); i++ {
		if i == len(values)-1 {
			placeholder.WriteString("?")
			placeholder.WriteString(internal.RightBracket)
			break
		}
		placeholder.WriteString("?")
		placeholder.WriteString(",")
	}
	return placeholder
}
